package jnpf.permission.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jnpf.permission.constant.PermissionConst;
import jnpf.permission.entity.*;
import jnpf.permission.mapper.OrganizeRelationMapper;
import jnpf.permission.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.permission.util.PermissionUtil;
import jnpf.util.RandomUtil;
import jnpf.util.StringUtil;
import lombok.Builder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织关系 服务实现类
 * </p>
 *
 * @author YanYu
 * @since 2022-01-19
 */
@Service
public class OrganizeRelationServiceImpl extends ServiceImpl<OrganizeRelationMapper, OrganizeRelationEntity> implements OrganizeRelationService {

    @Autowired
    RoleService roleService;
    @Autowired
    PositionService positionService;
    @Autowired
    UserRelationService userRelationService;
    @Autowired
    UserService userService;
    @Autowired
    AuthorizeService authorizeService;

    @Override
    public List<OrganizeRelationEntity> getRelationListByOrganizeId(List<String> organizeIds) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        if(organizeIds.size() == 0){
            organizeIds.add("");
        }
        query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeIds);
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<OrganizeRelationEntity> getRelationListByOrganizeId(List<String> organizeIds, String objectType) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, objectType);
        if(organizeIds.size() > 0){
            query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeIds);
        } else {
            organizeIds.add("");
            query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeIds);
        }
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<String> getPositionListByOrganizeId(List<String> organizeIds) {
        if(organizeIds.size() > 0){
            QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
            // 查询组织关系表集合
            query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.POSITION);
            query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeIds);
            query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
            return this.list(query).stream().map(OrganizeRelationEntity::getObjectId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public List<OrganizeRelationEntity> getRelationListByRoleId(String roleId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        query.lambda().in(OrganizeRelationEntity::getObjectId, roleId);
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<OrganizeRelationEntity> getRelationListByRoleIdList(List<String> roleId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        query.lambda().in(OrganizeRelationEntity::getObjectId, roleId);
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<OrganizeRelationEntity> getRelationListByObjectIdAndType(String objectType, String objectId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectId, objectId);
        query.lambda().eq(OrganizeRelationEntity::getObjectType, objectType);
        return this.list(query);
    }

    @Override
    public Boolean existByRoleIdAndOrgId(String roleId, String organizeId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        query.lambda().in(OrganizeRelationEntity::getObjectId, roleId);
        query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeId);
        return count(query) > 0;
    }

    @Override
    public Boolean existByObjTypeAndOrgId(String objectType, String organizeId) {
        return existByObjAndOrgId(objectType, null, organizeId);
    }

    @Override
    public Boolean existByObjAndOrgId(String objectType, String objId, String organizeId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectType, objectType);
        if(StringUtil.isNotEmpty(objId)){
            query.lambda().eq(OrganizeRelationEntity::getObjectId, objId);
        }
        query.lambda().in(OrganizeRelationEntity::getOrganizeId, organizeId);
        return count(query) > 0;
    }


    @Override
    public List<OrganizeRelationEntity> getRelationListByType(String objectType) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, objectType);
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<OrganizeRelationEntity> getListByTypeAndOrgId(String objectType, String orgId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        // 查询组织关系表集合
        query.lambda().eq(OrganizeRelationEntity::getObjectType, objectType).eq(OrganizeRelationEntity::getOrganizeId, orgId);
        query.lambda().orderByDesc(OrganizeRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public Boolean deleteAllByRoleId(String roleId) {
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        query.lambda().eq(OrganizeRelationEntity::getObjectId, roleId);
        return this.remove(query);
    }


    /*========================== 自动切换岗位，组织相关 ==============================*/


    @Override
    public String autoGetMajorPositionId(String userId, String currentMajorOrgId, String currentMajorPosId){
        // 属于该该组织底下的岗位
        List<PositionEntity> positionList = positionService.getListByOrgIdAndUserId(currentMajorOrgId, userId);
        if(positionList.size() > 0){
            // 默认岗位是否在此组织内，若存在不做切换
            if(positionList.stream().anyMatch(p -> p.getId().equals(currentMajorPosId))){
                return currentMajorPosId;
            }else{
                // 默认第一个岗位
                return positionList.get(0).getId();
            }
        }
        return "";
    }

    @Override
    public String autoGetMajorOrganizeId(String userId, List<String> userAllOrgIds, String currentMajorOrgId){
        if(userAllOrgIds.size() > 0){
            if (userAllOrgIds.contains(currentMajorOrgId) && checkBasePermission(userId, currentMajorOrgId)) {
                // 保持原默认组织不切换
                return currentMajorOrgId;
            }else{
                // 去除原本默认组织ID
                List<String> selectOrgIds = userAllOrgIds.stream().filter(usi-> !usi.equals(currentMajorOrgId)).collect(Collectors.toList());
                // 若不存在，强制切换有基本登录权限的角色
                for (String orgId : selectOrgIds) {
                    if (this.checkBasePermission(userId, orgId)) {
                        // 这个组织ID底下角色存在基础登录权限
                        return orgId;
                    }
                }
            }
            // 随机赋值一个
            return userAllOrgIds.get(0);
        }else {
            return "";
        }
    }




    /*== 自动key.equals ==*/

    @Override
    public void autoSetOrganize(List<String> allUpdateUserIds){
        if(allUpdateUserIds.size() > 0){
            for (UserEntity userEntity : userService.listByIds(allUpdateUserIds)) {
                String useId = userEntity.getId();
                String majorOrgId = userEntity.getOrganizeId();
                List<String> orgList = userRelationService.getListByObjectType(useId, PermissionConst.ORGANIZE)
                        .stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
                String changeOrgId = this.autoGetMajorOrganizeId(useId, orgList, majorOrgId);
                if(!changeOrgId.equals(majorOrgId)){
                    // 切换默认组织
                    UserEntity updateUserEntity = new UserEntity();
                    updateUserEntity.setId(useId);
                    updateUserEntity.setOrganizeId(changeOrgId);
                    userService.updateById(updateUserEntity);
                }
            }
        }
    }

    @Override
    public void autoSetPosition(List<String> allUpdateUserIds){
        if(allUpdateUserIds.size() > 0){
            for (UserEntity user : userService.listByIds(allUpdateUserIds)) {
                String majorPosId = user.getPositionId();
                String changePositionId = this.autoGetMajorPositionId(user.getId(), user.getOrganizeId(), majorPosId);
                if(!changePositionId.equals(majorPosId)){
                    UserEntity updateUser = new UserEntity();
                    updateUser.setId(user.getId());
                    updateUser.setPositionId(changePositionId);
                    userService.updateById(updateUser);
                }
            }
        }
    }


    /*===================== 权限判断 =======================*/

    @Override
    public Boolean checkBasePermission(String userId, String orgId){
        // 判断用户在某个组织下绑定的角色，是否有基本权限
        List<String> roles = roleService.getAllRoleIdsByUserIdAndOrgId(userId, orgId);
        for (String roleId : roles) {
            if(authorizeService.existByObjId(roleId)){
                return true;
            }
        }
        return false;
    }

}
